package cn.com.cifi.mars.config;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.MultipartConfigElement;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import cn.com.cifi.mars.common.redis.RedisTemplateUtil;
import cn.com.cifi.mars.web.filter.CrossDomainFilter;
import cn.com.cifi.mars.web.filter.SessionFilter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer, Converter<String, Date> {

    private static final List<String> formarts = new ArrayList();
    static {
        formarts.add("yyyy-MM");
        formarts.add("yyyy-MM-dd");
        formarts.add("yyyy-MM-dd HH");
        formarts.add("yyyy-MM-dd HH:mm");
        formarts.add("yyyy-MM-dd HH:mm:ss");
    }

    @Value("${cifi.application.mappingPath}")
    private String relativePath;

    @Value("${cifi.application.physicalPath}")
    private String physicalPath;

    @Bean
    ErrorProperties errorProperties() {
        return new ErrorProperties();
    }

    @Bean
    public CacheManager cacheManager() {
        SimpleCacheManager manager = new SimpleCacheManager();
        List<Cache> caches = new ArrayList<>(2);
        caches.add(new ConcurrentMapCache("CONFIG"));
        caches.add(new ConcurrentMapCache("DATA_DICT"));
        caches.add(new ConcurrentMapCache("QUERY"));
        manager.setCaches(caches);
        return manager;
    }

    @Bean
    public FilterRegistrationBean apiOriginFilter() {
        FilterRegistrationBean reg = new FilterRegistrationBean();
        reg.setFilter(new CrossDomainFilter());
        reg.setOrder(0);
        reg.addUrlPatterns("/api/*");
        return reg;
    }

    @Autowired
    private RedisTemplateUtil redisTemplateUtil;

    @Bean
    public FilterRegistrationBean userFilter(RedisTemplate<String, Object> template) {
        FilterRegistrationBean reg = new FilterRegistrationBean();
        SessionFilter filter = new SessionFilter();
        filter.setTemplate(redisTemplateUtil);
        reg.setFilter(filter);
        reg.setOrder(1);
        reg.addUrlPatterns("/api/*");
        return reg;
    }

    @Value("${spring.server.MaxFileSize}")
    private String MaxFileSize;
    @Value("${spring.server.MaxRequestSize}")
    private String MaxRequestSize;

    @Bean
    public MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        //  单个数据大小
        factory.setMaxFileSize(MaxFileSize);
        /// 总上传数据大小
        factory.setMaxRequestSize(MaxRequestSize);
        return factory.createMultipartConfig();
    }



    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler(relativePath).addResourceLocations("file:" + physicalPath);
    }

    @Override
    public Date convert(String source) {
        String value = source.trim();
        if ("".equals(value)) {
            return null;
        }
        if (source.matches("^\\d{4}-\\d{1,2}$")) {
            return parseDate(source, formarts.get(0));
        } else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")) {
            return parseDate(source, formarts.get(1));
        } else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}$")) {
            return parseDate(source, formarts.get(2));
        } else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")) {
            return parseDate(source, formarts.get(3));
        } else {
            throw new IllegalArgumentException("Invalid boolean value '" + source + "'");
        }
    }

    /**
     * 格式化日期
     *
     * @param dateStr String 字符型日期
     * @param format  String 格式
     * @return Date 日期
     */
    public Date parseDate(String dateStr, String format) {
        Date date = null;
        try {
            DateFormat dateFormat = new SimpleDateFormat(format);
            date = dateFormat.parse(dateStr);
        } catch (Exception e) {
            log.error("###### 格式化日期异常", e);
        }
        return date;
    }
}
